package com.scholarship.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;



/**
 * 上传下载工具类
 * @Author Z.J.H
 * @create 2021/9/10 14:45
 */
@Slf4j
@Component
public final class NewFileUtil {

    @Value("${path.upload}")
    private String uploadPath;

    @Value("${path.download}")
    private String downloadPath;

    //字符数组最大数量
    private final static int BUFFER_MAX_SIZE = 4096;

    public String getUploadPath() {
        File file = new File(uploadPath);
        if(!file.exists() && !file.isDirectory()) {
            file.mkdirs();
        }
        return uploadPath;
    }

    public String getDownloadPath() {
        File file = new File(uploadPath);
        if(!file.exists() && !file.isDirectory()) {
            file.mkdirs();
        }
        return downloadPath;
    }

    /**
     * 上传文件
     * @param multipartFile
     * @return 文件名
     */
    public String uploadFile(MultipartFile multipartFile) {
        //原始文件名称
        String originalFilename = multipartFile.getOriginalFilename();
        File file = new File(this.getUploadPath() + originalFilename);

        try {
            //写入磁盘
//            public void transferTo(Path dest) throws IOException, IllegalStateException {
//                FileCopyUtils.copy(this.part.getInputStream(), Files.newOutputStream(dest));
//            }
            multipartFile.transferTo(file);
        } catch (IOException e) {
            log.error(e.getMessage(),e);
        }
        return originalFilename;
    }

    /**
     * 下载文件
     * @param file
     * @param os
     */
    public void downloadFile(File file, OutputStream os) {

        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;
        try {
            bos = new BufferedOutputStream(os);
            bis = new BufferedInputStream(new FileInputStream(file));

            byte[] bytes = new byte[BUFFER_MAX_SIZE];
            int len = 0;

            while((len = bis.read(bytes)) != -1) {
                bos.write(bytes, 0, len);
            }
        } catch (IOException e) {
            log.error(e.getMessage(),e);
        } finally {
            if(bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    log.error(e.getMessage(),e);
                } finally {
                    if(bis != null) {
                        try {
                            bis.close();
                        } catch (IOException e) {
                            log.error(e.getMessage(),e);
                        }
                    }
                }
            }
        }
    }

    /**
     * 下载压缩包
     * @param files
     * @param os
     * @throws IOException
     */
    public void downloadZip(List<File> files, OutputStream os) {

        ZipOutputStream zos = null;
        try {
            zos = new ZipOutputStream(os);
            for(File file : files) {
                ZipEntry zipEntry = new ZipEntry(file.getName());
                zos.putNextEntry(zipEntry);

                byte[] bytes =  new byte[BUFFER_MAX_SIZE];
                int len = 0;

                BufferedInputStream bis = null;
                try {
                    bis = new BufferedInputStream(new FileInputStream(file));
                    while((len = bis.read(bytes)) != -1) {
                        zos.write(bytes, 0, len);
                        zos.flush();
                    }
                } catch (IOException e) {
                    log.error(e.getMessage(),e);
                } finally {
                    if(bis != null) {
                        try {
                            bis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        } catch (IOException e) {
            log.error(e.getMessage(),e);
        } finally {
            if(zos != null) {
                try {
                    zos.close();
                } catch (IOException e) {
                    log.error(e.getMessage(),e);
                }
            }
        }

    }
}
